#pragma once
#include "Transform.h"
#include "DAEFloat3.h"
/**
* This class can be used to create a transformation
* object that translates vectors (DAEFloat3) to 
* a new local axis.
* A local axis needs the following parameters :
* 1. An X axis (DAEFloat3)
* 2. An Y axis (DAEFloat3)
* 3. A Z axis (DAEFloat3)
* 4. An origin (DAEFloat3)
*
* This class can also be used for the camera class.
* 1. The up vector for the camera corresponds with the Y vector.
* 2. The look vector for the camera corresponds with the Z vector.
* 3. The right vector for the camera corresponds with the X vector.
* 4. The camera position corresponds with the origin.
* @author Koen Samyn
*/
class LocalAxisTransform: public Transform
{
public:
	/**
	* Constructs a new LocalAxisTransform
	*/
	LocalAxisTransform(void);
	/**
	* Destroys the view transform object.
	*/ 
	virtual ~LocalAxisTransform(void);
	/**
	* Set the axis and origin for the transformation.
	* No attempt will be made to make the axis orthogonal and
	* of unit length.
	* @param origin the origin for the transformation.
	* @param xAxis the new xAxis
	* @param yAxis the new yAxis
	* @param zAxis the new zAxis.
	*/
	void SetAxis(DAEFloat3 origin, DAEFloat3 xAxis, DAEFloat3 yAxis, DAEFloat3 zAxis);
	/**
	* Creates a Camera transform. An orthogonal and unit length system will be created.
	* @param rightHanded if true, this will be a right handed camera transform, if false
	* it will be a left handed camera transform.
	* @param eye the position of the camera.
	* @param look the position the camera is looking at.
	* @param up the up vector for the camera.
	*/
	void SetCameraTransform(bool rightHanded, DAEFloat3 eye, DAEFloat3 look, DAEFloat3 up);
	/**
	* Normalizes the 3 axis objects.
	*/
	void Normalize();
	/**
	* Returns the X axis for this transform.
	* @return the X axis as DAEFloat3 object.
	*/
	const DAEFloat3& GetXAxis() const {return m_X;}
	/**
	* Returns the "Right" vector for this transform.
	* Synonym for GetXAxis.
	* @return the right vector (x axis) as DAEFloat3 object.
	*/
	const DAEFloat3& GetRightVector() const{return m_X;}
	/**
	* Returns the Y axis for this transform.
	* @return the Y axis as DAEFloat3 object.
	*/
	const DAEFloat3& GetYAxis() const{return m_Y;}
	/**
	* Returns the "Up" vector for this transform.
	* Synonym for GetYAxis.
	* @return the right vector (x axis) as DAEFloat3 object.
	*/
	const DAEFloat3& GetUpVector() const{return m_Y;}
	/**
	* Returns the Z axis for this transform.
	* @return the z axis as DAEFloat3 object.
	*/ 
	const DAEFloat3& GetZAxis() const{return m_Z;}
	/**
	* Gets the view direction of this LocalAxisTransform
	* Synonym for GetXAxis.
	* @return the view direction (z axis) from this LocalAxisTransform.
	*/
	const DAEFloat3& GetLookVector() const{return m_Z;}
	/**
	* Gets the origin for the view transform.
	* @return the DAEFloat3 object with the origin.
	*/
	const DAEFloat3& GetOrigin()const{return m_Origin;}
	/**
	* Sets the origin for the view transform.
	* @param x the new x value for the origin.
	* @param y the new y value for the origin.
	* @param z the new z value for the origin.
	*/ 
	void SetOrigin(float x, float y, float z){
		m_Changed=true;
		m_Origin.x=x;
		m_Origin.y=y;
		m_Origin.z=z;
	}
	/**
	* Transforms the Y or up vector with the provided transform
	* @param transform the transform to use on the Y or up axis.
	*/
	void TransformLookAndUpVector(const Transform& t);

	/**
	* Resets the parameters of the transform.
	* Must be implemented by subclass.
	*/
	void ResetTransformParameters();
	/**
	* Recalculates the matrix
	*/
	void RecalculateMatrix() const; 
private:

	/**
	* The new x axis.
	*/
	DAEFloat3 m_X;
	/**
	* The new y axis.
	*/ 
	DAEFloat3 m_Y;
	/**
	* The new z axis.
	*/
	DAEFloat3 m_Z;
	/** 
	* The origin for the camera.
	*/ 
	DAEFloat3 m_Origin;
	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	LocalAxisTransform(const LocalAxisTransform& t);
	LocalAxisTransform& operator=(const LocalAxisTransform& t);
};
